import {Generator} from "./Generator";
import {PluginFunctionType, Point} from "../../nodeApp/static/lib/crowncad-plugin-sdk-0.0.1";

class ChainGenerator extends Generator {
  constructor() {
    super();
  }

  /**
   * 创建滚子链条
   */
  createRollerChain(rollerChain, cb = () => {}) {
    const sketch = this.command.sketch;
    const solid = this.command.solid;
    // 创建草图
    this.createRefSketch(sketch, rollerChain.pitch, rollerChain.innerPlateHight, rollerChain.pinD, rollerChain.rollerD);
    this.command.execute(true).then(() => {
      this.command.clearCommand();
      this.createOuterPlateSketch(sketch).then(() => {
        this.command.execute().then(() => {  // 执行
          this.command.clearCommand();
          this.extrudeInnerPlate(solid, rollerChain.thickness).then(() => {  // 拉伸内链片
            this.command.execute().then(() => {
              this.command.clearCommand();
              this.extrudeRoller(solid, rollerChain.innerPlateDis).then(() => {  // 拉伸滚子
                this.command.execute().then(() => {
                  this.command.clearCommand();
                  const pinLength = (rollerChain.pinLength - rollerChain.innerPlateDis) / 2;
                  this.extrudePin(solid, pinLength).then(() => {  // 拉伸销轴
                    this.command.execute().then(() => {
                      this.command.clearCommand();
                      this.createMirrorDatum(this.command.datum, rollerChain.innerPlateDis / 2);  // 镜像面
                      this.command.execute().then(() => {
                        this.command.clearCommand();
                        this.createInnerPlaneMirror(solid).then(() => {
                          this.command.execute().then(() => {
                            this.command.clearCommand();
                            this.createPinMirror(solid).then(() => {
                              this.command.execute().then(() => {
                                this.command.clearCommand();
                                this.extrudeOuterPlate(solid, rollerChain.thickness).then(() => {
                                  this.command.execute().then(() => {
                                    this.command.clearCommand();
                                    this.createOuterPlaneMirror(solid).then(() => {
                                      this.command.execute().then(()=> {
                                        this.command.clearCommand();
                                        cb();
                                      });
                                    });
                                  });
                                });
                              });
                            });
                          });
                        });
                      });
                    });
                  });
                });
              });
            });
          });
        });
      });
    });
  }

  /**
   * 创建内链片、滚子、销轴草图
   */
  createRefSketch(sketch, p, h2, d2, d1) {
    const centerL = new Point(0 - p / 2, 0);
    const centerR = new Point(p / 2, 0);
    const x0 = p / 2;
    const y0 = 0;
    const x1 = 0;
    const y1 = 2.63 * p;
    const radius0 = h2 / 2;
    const radius1 = Math.sqrt((y1 * y1) + (x0 * x0)) - radius0;
    const vX = x1 - x0;
    const vY = y1 - y0;
    const k = radius0 / (radius0 + radius1);
    const interX = x0 + k * vX;
    const interY = y0 + k * vY;

    // 草图1：内链片
    sketch.createSketch({sketchName: '草图1', datumId: 8});
    sketch.createArcByCenter({
      centerPoint: centerR, startPoint: new Point(interX, 0 - interY), endPoint: new Point(interX, interY)
    });
    sketch.createArcByCenter({
      centerPoint: centerL, startPoint: new Point(0 - interX, interY), endPoint: new Point(0 - interX, 0 - interY)
    });
    sketch.createArcByCenter({
      centerPoint: new Point(x1, y1), startPoint: new Point(0 - interX, interY), endPoint: new Point(interX, interY)
    });
    sketch.createArcByCenter({
      centerPoint: new Point(x1, 0 - y1),
      startPoint: new Point(interX, 0 - interY),
      endPoint: new Point(0 - interX, 0 - interY)
    });
    sketch.createCircle({
      centerPoint: centerL, circlePoint: new Point(0 - p / 2, d2 / 2)
    });
    sketch.createCircle({
      centerPoint: centerR, circlePoint: new Point(p / 2, d2 / 2)
    });

    sketch.createReferenceLine({startPoint: new Point(0, -100.203), endPoint: new Point(p / 2, 0)});
    sketch.exitSketch();

    // 草图2：滚子
    sketch.createSketch({sketchName: '草图2', datumId: 8});
    sketch.createCircle({
      centerPoint: centerL, circlePoint: new Point(0 - p / 2, d1 / 2)
    });
    sketch.createCircle({
      centerPoint: centerR, circlePoint: new Point(p / 2, d1 / 2)
    });
    sketch.exitSketch();

    // 草图3：销轴
    sketch.createSketch({sketchName: '草图3', datumId: 8});
    sketch.createCircle({
      centerPoint: centerL, circlePoint: new Point(0 - p / 2, d2 / 2)
    });
    sketch.createCircle({
      centerPoint: centerR, circlePoint: new Point(p / 2, d2 / 2)
    });
    sketch.exitSketch();
  }

  /**
   * 创建外链片草图
   */
  createOuterPlateSketch(sketch) {
    return new Promise(resolve => {
      this.request.execFunction(PluginFunctionType.getElementsByFeatureNames, {featureNames: ['草图1']}).then(elements => {
        const elementIds = [];
        let axisId;
        sketch.createSketch({sketchName: '草图4', datumId: 8});
        elements.elements.forEach(element => {
          if (element.params.type === 12 || element.params.type === 11) {
            elementIds.push(element.id);
          }
          if (element.params.type === 10) {
            axisId = element.id;
          }
        });
        sketch.createMirror({elementIds: elementIds, axisId: axisId});
        sketch.exitSketch();
        resolve();
      });
    });
  }

  /**
   * 拉伸内链片
   */
  extrudeInnerPlate(solid, t) {
    return new Promise(resolve => {
      this.request.execFunction(PluginFunctionType.getEntitiesByFeatureNames, {featureNames: ['草图1']}).then(res => {
        if (res?.entities) {
          solid.extrude({
            sketch: res.entities[0].id,
            reverse: 1,
            height1: t
          }, '内链片');
          resolve();
        }
      });
    });
  }

  /**
   * 拉伸外链片
   */
  extrudeOuterPlate(solid, t) {
    return new Promise(resolve => {
      this.request.execFunction(PluginFunctionType.getEntitiesByFeatureNames, {featureNames: ['草图4']}).then(res => {
        if (res?.entities) {
          solid.extrude({
            sketch: res.entities[0].id,
            reverse: 1,
            height1: t,
            offsetType: 0,
            distance: t,
            reverseOffset: 1
          }, '外链片');
          resolve();
        }
      });
    });
  }

  /**
   * 拉伸滚子
   */
  extrudeRoller(solid, b1) {
    return new Promise(resolve => {
      this.request.execFunction(PluginFunctionType.getEntitiesByFeatureNames, {featureNames: ['草图2']}).then(res => {
        if (res?.entities) {
          solid.extrude({
            sketch: res.entities[0].id,
            height1: b1
          }, '滚子');
          resolve();
        }
      });
    });
  }

  /**
   * 拉伸销轴
   */
  extrudePin(solid, l) {
    return new Promise(resolve => {
      this.request.execFunction(PluginFunctionType.getEntitiesByFeatureNames, {featureNames: ['草图3']}).then(res => {
        if (res?.entities) {
          solid.extrude({
            sketch: res.entities[0].id,
            reverse: 1,
            height1: l
          }, '销轴');
          resolve();
        }
      });
    });
  }

  /**
   * 创建镜像面
   */
  createMirrorDatum(datum, dis) {
    datum.createPlaneByDistance({
      planeId: 8,
      invertNormal: 0,
      paralDis: dis,
      reverse: 0,
    }, '镜像面');
  }

  /**
   * 镜像内链片
   */
  createInnerPlaneMirror(solid) {
    return new Promise(resolve => {
      this.request.execFunction(PluginFunctionType.getEntitiesByFeatureNames, {featureNames: ['镜像面']}).then(res => {
        if (res?.entities) {
          this.request.execFunction(PluginFunctionType.getEntitiesByFeatureNames, {featureNames: ['内链片']}).then(feature => {
            if (feature?.entities) {
              solid.mirrorSolid({
                baseType: 0,
                body: feature.entities[0].id,
                mirrorPlane: res.entities[0].id,
                mergeSolids: 0,
                geometryPattern: 0,
              }, '内链片2');
              resolve();
            }
          });
        }
      });
    });
  }

  /**
   * 镜像销轴
   */
  createPinMirror(solid) {
    return new Promise(resolve => {
      this.request.execFunction(PluginFunctionType.getEntitiesByFeatureNames, {featureNames: ['镜像面']}).then(res => {
        if (res?.entities) {
          this.request.execFunction(PluginFunctionType.getEntitiesByFeatureNames, {featureNames: ['销轴']}).then(feature => {
            if (feature?.entities) {
              solid.mirrorSolid({
                baseType: 0,
                body: feature.entities[0].id,
                mirrorPlane: res.entities[0].id,
                mergeSolids: 0,
                geometryPattern: 0,
              }, '销轴2');
              resolve();
            }
          });
        }
      });
    });
  }

  /**
   * 镜像外链片
   */
  createOuterPlaneMirror(solid) {
    return new Promise(resolve => {
      this.request.execFunction(PluginFunctionType.getEntitiesByFeatureNames, {featureNames: ['镜像面']}).then(res => {
        if (res?.entities) {
          this.request.execFunction(PluginFunctionType.getEntitiesByFeatureNames, {featureNames: ['外链片']}).then(feature => {
            if (feature?.entities) {
              solid.mirrorSolid({
                baseType: 0,
                body: feature.entities[0].id,
                mirrorPlane: res.entities[0].id,
                mergeSolids: 0,
                geometryPattern: 0,
              }, '外链片2');
              resolve();
            }
          });
        }
      });
    });
  }

  /**
   * 处理点坐标的误差
   */
  getPoint(point) {
    const x = Math.abs(point.x) < 1e-10 ? 0 : point.x;
    const y = Math.abs(point.y) < 1e-10 ? 0 : point.y;
    return new Point(x, y);
  }
}

const chainGenerator = new ChainGenerator();
export {chainGenerator};
